//
//  Person1.swift
//  Swift_base_grammar
//
//  Created by lantaiyuan on 2017/9/14.
//  Copyright © 2017年 lantaiyuan. All rights reserved.
//

import UIKit
/**
 构造函数 － 建立一个`对象`
 1. 给属性分配空间
 2. 设置初始数值
 
 Swift 中构造函数`都`是 init
 
 重载：OC中没有重载的概念
 
 函数名相同，参数的个数&类型不同，叫做重载，是面向对象设计语言必备标志！
 OC 中使用 initWithXXX的方式替代
 */
class Person1: NSObject {
    
    
    /*
     // 对象的属性就是应该可变的
     // 可选项，允许变量为空，var 的默认值就是 nil
     var name : String
     var age : Int
     
     /// 重写 默认构造函数
     // `重写`默认的构造函数
     // 父类提供了这个函数，而子类需要对父类的函数进行扩展，就叫做重写
     // 特点：可以 super.xxx 调用父类本身的方法
     override init() {
     name = "张三"
     age = 18
     //调用父类的构造函数
     super.init()
     }
     */
    
    /*
     
     // 对象的属性就是应该可变的
     // 可选项，允许变量为空，var 的默认值就是 nil
     var name : String
     var age : Int
     
     
     /// 重载的构造函数 ---只要是构造函数就要给属性设置初始值
     /// 如果重写了构造函数，系统默认提供的`构造函数 init()`，就不能再被访问
     
     init(name:String,age:Int) {
     self.name = name
     self.age = age
      }
     */
    
   
    //KVC 构造函数
    /*
     
     //设置属性
     var name:String?
     var age:Int = 0
     
     //KVC 构造函数,用字典设置模型
     init(dict:[String:AnyObject]) {
     // KVC 是 OC 特有的，本质是在运行时，动态的给`对象`发送 `setVaule:forKey:` 消息
     // 设置数值 - 调用 super.init 保证对象已经被创建完成
     super.init()
     
     // KVC 的设置数值
     setValuesForKeys(dict)
     }
     
     override func setValue(_ value: Any?, forKey key: String) {
     super.setValue(value, forKey: key)
     }
     
     /// 默认的 setValue forUndefinedKey 方法如果出现未定义的key会抛出 `NSUndefinedKeyException`异常，让程序崩溃
     /// 如果一旦重写了此方法，同时不 super，不调用父类默认的方法！
     override func setValue(_ value: Any?, forUndefinedKey key: String) {
     print("forUndefinedKey\(key):\(value ?? "")")
     }
     
     */
    
    var name:String?
    var age:Int = 0
    /**
     与 dealloc 类似，主要是负责对象被销毁之前的`内存释放`工作
     1. 没有 func
     2. 没有 () -> 不允许重载，不允许带参数，不允许直接调用，在系统内部自动调用的
     
     在实际开发中，哪些内容需要程序员销毁？
     - 通知，如果不注销，程序不会崩溃
     - KVO，如果不注销，程序会崩溃
     - NSTimer，会对 target（self），进行强引用
     */
    deinit {
        print("person 88")
    }
    // 构造函数中，如果出现 ?，表示这个构造函数不一定会创建出对象
    // convenience - 便利构造函数
    // 作用
    // 1. 能够提供条件检测
    // 2. 能够允许返回 nil，默认(指定)的构造函数，必须要创建对象
    // 3. 便利构造函数，必须在条件检测完成之后，以 self. 的方式调用其他的构造函数，创建对象
    // 4. 能够简化对象的创建方法
    convenience init?(name:String,age:Int) {
        if age < 0 || age > 100 {
            //不能创建对象
            return nil
        }
        // 调用其他的构造函数初始化属性 － 在一个构造函数中调用了另外一个构造函数
        self.init(dict: ["name":name as AnyObject,"age":age as AnyObject])
    }
    /// KVC 的构造函数，用字典设置模型
    init(dict:[String:AnyObject]) {
        super.init()
        //设置数值
        setValuesForKeys(dict)
    }
    override func setValue(_ value: Any?, forKey key: String) {
         print("forKey \(key) - \(String(describing: value))")
        super.setValue(value, forKey: key)
    }
    override func setValue(_ value: Any?, forUndefinedKey key: String) {
         print("forKey \(key) - \(String(describing: value))")
    }
}
